module nco_gen #(
    parameter DATA_WIDTH = 13,//Signed Width
    parameter DATA_COUNT = 1024,//DDS ROM DATA COUNT
    parameter DATA_COUNT_LOG2 = 10,//DATA_COUNT WIDTH
    parameter PHASE_WIDTH = 16,//PHASE WIDTH
    parameter INIT_PHASE  = 16384
)
(
    input  wire                                 sys_clk,
    input  wire                                 sys_rst,
    input  wire                                 enable,
    input  wire         [PHASE_WIDTH -1 :0 ]    freq_word,//initial phase

    output reg signed   [DATA_WIDTH  -1 :0 ]    out_data, //output signed sine wave
    output wire                                 valid    
);

reg signed  [DATA_WIDTH  - 1 :0 ] sin_data;
reg         [PHASE_WIDTH - 1 :0 ] phase_reg;
reg         [              1 :0 ] enable_reg;
reg [DATA_WIDTH  - 2 :0 ] sin_rom [0 :DATA_COUNT - 1 ];


initial begin
    $readmemh("sine.txt",sin_rom);
end

//Valid output
always @ (posedge sys_clk)
    if(sys_rst)
        enable_reg <= 0;
    else begin
        enable_reg[0] <= enable;
        enable_reg[1] <= enable_reg[0];
    end

assign valid = enable_reg[1];

//Phase Counter
always @ (posedge sys_clk)
    if(sys_rst)
        phase_reg <= INIT_PHASE;
    else if(enable)
        phase_reg <= phase_reg + freq_word;
    else
        phase_reg <= INIT_PHASE;

//Read rom and convert to signed
always @ (posedge sys_clk)
    if(sys_rst)
        sin_data <= 0;
    else if(enable)
        sin_data <= {1'b0,sin_rom[phase_reg[PHASE_WIDTH - 1 : PHASE_WIDTH - DATA_COUNT_LOG2]]};

//Remove DC signal and output
always @ (posedge sys_clk)
    if(sys_rst)
        out_data <= 0;
    else if(enable_reg[0])
        out_data <= sin_data - {1'b0,1'b1,{(DATA_WIDTH - 2){1'b0}}};

endmodule